home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / DYN401.ZIP / threads / pipe.d < prev    next >
Text File  |  1996-02-04  |  6KB  |  320 lines

  1.  
  2.  
  3.  
  4.  
  5. /*
  6.  *
  7.  *    Copyright (c) 1993-1996 Algorithms Corporation
  8.  *    3020 Liberty Hills Drive
  9.  *    Franklin, TN  37067
  10.  *
  11.  *    ALL RIGHTS RESERVED.
  12.  *
  13.  *
  14.  *
  15.  */
  16.  
  17.  
  18. #include <string.h>
  19.  
  20.  
  21. defclass  Pipe : Stream  {
  22.     object    iObj;        /*  pipe object        */
  23.     char    *iName;
  24.     char    *iBuf;
  25.     int    iBufsiz;
  26.     char    *iWptr;    /*  write pointer (where next byte should go)    */
  27.     char    *iRptr;    /*  read pointer (where next byte will be)    */
  28.     object    iRblk;    /*  thread on read block            */
  29.     object    iWblk;    /*  thread on write block            */
  30.     int    iRblock;/*  block reads when buffer empty        */
  31.     int    iWblock;/*  block writes when buffer full        */
  32.     struct _Pipe_iv_t    *iNext;
  33.  class:
  34.     struct _Pipe_iv_t    *cMpl;    /*  master pipe list        */
  35. };
  36.  
  37.  
  38. cmeth    gNewWithStrInt, <vNew> : New (object self, char *name, int bufsiz)
  39. {
  40.     object    obj = gNew(super);
  41.     ivType    *iv = ivPtr(obj);
  42.     
  43.     iObj = obj;
  44.     if (name)  {
  45.         iName = Tnalloc(char, strlen(name)+1);
  46.         strcpy(iName, name);
  47.     }
  48.     iBuf = Tnalloc(char, bufsiz);
  49.     iBufsiz = bufsiz;
  50.     iWptr = iRptr = iBuf;
  51.     iNext = cMpl;
  52.     cMpl = iv;
  53.     return obj;
  54. }
  55.  
  56. cmeth    gNew()
  57. {
  58.     return New(self, NULL, 128);
  59. }
  60.  
  61. imeth    int    gWrite(object self, char *buf, unsigned sz)
  62. {
  63.     int    room, rroom, bytes, w=0;
  64.     
  65.     if (iWblk)
  66.         return 0;
  67.     while (sz)  {
  68.         /*  how much room is left on the write end of the buffer?  */
  69.  
  70.         room = iBufsiz - (iWptr - iBuf);
  71.         
  72.         /*  if not enough make room from read end   */
  73.     
  74.         if (room < (int) sz)  {
  75.             rroom = iRptr - iBuf;
  76.             if (rroom)  {
  77.                 bytes = iWptr - iRptr; /* bytes in buffer  */
  78.                 memmove(iBuf, iRptr, bytes);
  79.                 iRptr = iBuf;
  80.                 iWptr = iBuf + bytes;
  81.                 room = iBufsiz - (iWptr - iBuf);
  82.             }
  83.         }
  84.  
  85.         bytes = (int) sz > room ? room : (int) sz; /*  bytes to but on buffer  */
  86.         if (bytes)  {
  87.             memcpy(iWptr, buf, bytes);
  88.             iWptr += bytes;
  89.             buf += bytes;
  90.             sz -= bytes;
  91.             w += bytes;
  92.             if (iRblk)
  93.                 gRelease(iRblk, 0);
  94.         }
  95.         /*  the following line is needed because the above release might have cause
  96.             more room - if the read thread has a higher priority  */
  97.         room = iBufsiz - (iWptr - iRptr);
  98.         if (sz  &&  !room  &&  iWblock)  { /*  there is more - block  */
  99.             iWblk = gFindStr(Thread, NULL);
  100.             gHold(iWblk); /*  does a yield  */
  101.             iWblk = NULL;
  102.         }
  103.         if (!iWblock)
  104.             break;
  105.     }
  106.     return(w);
  107. }
  108.  
  109. imeth    int    gRead(object self, char *buf, unsigned sz)
  110. {
  111.     int    ba;    /*  bytes available    */
  112.     int    bg;    /*  bytes to get    */
  113.     int    tr=0;    /*  total bytes read    */
  114.     
  115.     if (iRblk)
  116.         return 0;
  117.     while (sz)  {
  118.         ba = iWptr - iRptr;
  119.         bg = ba < (int) sz ? ba : (int) sz;
  120.         if (bg)  {
  121.             memcpy(buf, iRptr, bg);
  122.             buf += bg;
  123.             iRptr += bg;
  124.             sz -= bg;
  125.             tr += bg;
  126.             if (iWblk)
  127.                 gRelease(iWblk, 0);
  128.         }
  129. /*  the following line is needed because the above release may add bytes */
  130.         ba = iWptr - iRptr;
  131.         if (sz  &&  !ba  &&  iRblock)  {
  132.             iRblk = gFindStr(Thread, NULL);
  133.             gHold(iRblk); /*  does a yield  */
  134.             iRblk = NULL;
  135.         }
  136.         if (!iRblock)
  137.             break;
  138.     }
  139.     return(tr);
  140. }
  141.  
  142. imeth    char    *gGets(object self, char *buf, int sz)
  143. {
  144.     int    ba;    /*  bytes available    */
  145.     int    bg;    /*  bytes to get    */
  146.     int    tr=0;    /*  total bytes read    */
  147.     
  148.     if (!(iWptr - iRptr) && !iRblock  ||  iRblk  ||  sz <= 0)
  149.         return NULL;
  150.     if (sz-- == 1)  {
  151.         *buf = '\0';
  152.         return buf;
  153.     }
  154.     while (sz)  {
  155.         ba = iWptr - iRptr;
  156.         for (bg=0 ; bg < ba  &&  bg < sz  &&  iRptr[bg++] != '\n' ; );
  157.         if (iRptr[bg-1] == '\n')
  158.             sz = bg;
  159.         if (bg)  {
  160.             memcpy(buf, iRptr, bg);
  161.             buf += bg;
  162.             iRptr += bg;
  163.             sz -= bg;
  164.             tr += bg;
  165.             if (iWblk)
  166.                 gRelease(iWblk, 0);
  167.         }
  168. /*  the following line is needed because the above release may add bytes */
  169.         ba = iWptr - iRptr;
  170.         if (sz  &&  !ba  &&  iRblock)  {
  171.             iRblk = gFindStr(Thread, NULL);
  172.             gHold(iRblk); /*  does a yield  */
  173.             iRblk = NULL;
  174.         }
  175.         if (!iRblock)
  176.             break;
  177.     }
  178.     buf[tr] = '\0';
  179.     return buf;
  180. }
  181.  
  182. imeth    object    gDispose, gGCDispose, gDeepDispose (object self)
  183. {
  184.     ivType    *t, *pt;
  185.  
  186.     if (iRblk  ||  iWblk)
  187.         return NULL;
  188.     for (t=cMpl, pt=NULL ; t ; pt=t, t=t->iNext)
  189.         if (t == iv)  {
  190.             if (pt)
  191.                 pt->iNext = t->iNext;
  192.             else
  193.                 cMpl = t->iNext;
  194.             break;
  195.         }
  196.     if (iName)  {
  197.         free(iName);
  198.         iName = NULL;
  199.     }
  200.     if (iBuf)  {
  201.         free(iBuf);
  202.         iBuf = NULL;
  203.     }
  204.     return gDispose(super);
  205. }
  206.  
  207. cmeth    object    gFindStr, <vFind> (object self, char *name)
  208. {
  209.     ivType    *p;
  210.     
  211.     USE(self);
  212.     if (!name)
  213.         return NULL;
  214.     for (p=cMpl ; p ; p=p->iNext)
  215.         if (p->iName  &&  !strcmp(p->iName, name))
  216.             return p->iObj;
  217.     return NULL;
  218. }
  219.  
  220. imeth    long    gLength(object self)
  221. {
  222. #if 0
  223.     if (iRblock  &&  !(iWptr - iRptr))  {
  224.         iRblk = gFindStr(Thread, NULL);
  225.         gHold(iRblk); /*  does a yield  */
  226.         iRblk = NULL;
  227.     }
  228. #endif
  229.     return iWptr - iRptr;
  230. }
  231.  
  232. imeth    int    gRoom(object self)
  233. {
  234. #if 0
  235.     if (iWblock  &&  !(iBufsiz - (iWptr - iRptr)))  {
  236.         iWblk = gFindStr(Thread, NULL);
  237.         gHold(iWblk); /*  does a yield  */
  238.         iWblk = NULL;
  239.     }
  240. #endif
  241.     return iBufsiz - (iWptr - iRptr);
  242. }
  243.  
  244. imeth    int    gSize(object self)
  245. {
  246.     return iBufsiz;
  247. }
  248.  
  249. imeth    char    *gName(object self)
  250. {
  251.     return iName;
  252. }
  253.  
  254. imeth    gMode(object self, int rblock, int wblock)
  255. {
  256.     iRblock = rblock;
  257.     iWblock = wblock;
  258.     return self;
  259. }
  260.  
  261. imeth    long    gAdvance(object self, long sz)
  262. {
  263.     int    ba;    /*  bytes available    */
  264.     int    bg;    /*  bytes to get    */
  265.     long    tr=0;    /*  total bytes read    */
  266.     
  267.     if (iRblk)
  268.         return 0;
  269.     while (sz)  {
  270.         ba = iWptr - iRptr;
  271.         bg = (long) ba < sz ? ba : (int) sz;
  272.         if (bg)  {
  273.             iRptr += bg;
  274.             sz -= bg;
  275.             tr += bg;
  276.             if (iWblk)
  277.                 gRelease(iWblk, 0);
  278.         }
  279. /*  the following line is needed because the above release may add bytes */
  280.         ba = iWptr - iRptr;
  281.         if (sz  &&  !ba  &&  iRblock)  {
  282.             iRblk = gFindStr(Thread, NULL);
  283.             gHold(iRblk); /*  does a yield  */
  284.             iRblk = NULL;
  285.         }
  286.         if (!iRblock)
  287.             break;
  288.     }
  289.     return(tr);
  290. }
  291.  
  292. imeth    long    gPosition(object self)
  293. {
  294.     USE(self);
  295.     return 0L;
  296. }
  297.  
  298. imeth    int    gEndOfStream(object self)
  299. {
  300.     return !(iWptr - iRptr);
  301. }
  302.  
  303.  
  304.  
  305.  
  306. /*
  307.  *
  308.  *    Copyright (c) 1993-1996 Algorithms Corporation
  309.  *    3020 Liberty Hills Drive
  310.  *    Franklin, TN  37067
  311.  *
  312.  *    ALL RIGHTS RESERVED.
  313.  *
  314.  *
  315.  *
  316.  */
  317.  
  318.  
  319.  
  320.